Skip to content

Improve TypeManager.function/TypeManager.virtual_function fetch speed by using cache.#479

Open
CookStar wants to merge 5 commits intoSource-Python-Dev-Team:masterfrom
CookStar:speedup_function
Open

Improve TypeManager.function/TypeManager.virtual_function fetch speed by using cache.#479
CookStar wants to merge 5 commits intoSource-Python-Dev-Team:masterfrom
CookStar:speedup_function

Conversation

@CookStar
Copy link
Contributor

@CookStar CookStar commented Jun 14, 2023

Entity has a mechanism to speed up the retrieval of dynamic_attributes/server_classes, but TypeManager itself does not. With this improvement, instances created by TypeManager can speed up the retrieval of function/virtual_function.

In virtual_function, I tried to improve the performance by using type_info and caching, but it did not improve the performance.

Test Code (CS:GO/Linux):

import time

from memory import find_binary
from memory import make_object
from memory.manager import CustomType
from memory.manager import TypeManager

""" TypeManager.function Test"""

# _ZN9CCSPlayer12RoundRespawnEv
signature = b"\x55\x89\xE5\x56\x53\x83\xEC\x1C\x8B\x5D\x08\xFF\x35\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x10\x84\xC0\x0F\x85\x2A\x2A\x2A\x2A\x8B\x13"

# Cache signature
find_binary("server", srv_check=False)[signature]

manager = TypeManager()

class Test(CustomType, metaclass=manager):
    _binary = "server"
    _srv_check = False
    _size = 0

    _spawn = manager.function(signature)

# Cache function
Test._spawn

s = time.perf_counter()
for i in range(100000):
    Test._spawn
e = time.perf_counter()
print(e-s, "Test._spawn")

# Cache function
test = Test()
test._spawn

s = time.perf_counter()
for i in range(100000):
    test._spawn
e = time.perf_counter()
print(e-s, "test._spawn")

l = [Test() for i in range(100000)]

s = time.perf_counter()
for i in range(100000):
    l[i]._spawn
e = time.perf_counter()
print(e-s, "Test()._spawn")

""" TypeManager.virtual_function Test"""

manager = TypeManager()

class Test(CustomType, metaclass=manager):
    blind = manager.virtual_function(551, (DataType.FLOAT, DataType.FLOAT, DataType.FLOAT))

pointer = Entity.find("player").pointer
test = make_object(Test, pointer)
test.blind

s = time.perf_counter()
for i in range(100000):
    test.blind
e = time.perf_counter()
print(e-s, "test.blind")

l = [make_object(Test, pointer) for i in range(100000)]

s = time.perf_counter()
for i in range(100000):
    l[i].blind
e = time.perf_counter()
print(e-s, "make_object(Test, pointer).blind")

Since the implementation has changed, the test results have also changed.
Output :

TypeManager.function Test
4.355441149324179 Test._spawn
4.830625455826521 test._spawn
4.801660872995853 Test()._spawn
↓
OLD: 0.02216128632426262 Test._spawn
OLD: 0.008792959153652191 test._spawn
OLD: 0.2989997826516628 Test()._spawn

NEW: 0.023133378475904465 Test._spawn
NEW: 0.29126785323023796 test._spawn
NEW: 0.293557733297348 Test()._spaw

TypeManager.virtual_function Test
0.5497394129633904 test.blind
0.5683586820960045 make_object(Test, pointer).blind
↓
OLD: 0.008566077798604965 test.blind
OLD: 0.5120681896805763 make_object(Test, pointer).blind

NEW: 0.46108797565102577 test.blind
NEW: 0.4727563001215458 make_object(Test, pointer).blind

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants